#pragma once
#include <iostream>
#include <string>
#include <functional>
#include "Socket.hpp"
#include "Reactor.hpp"
#include "Log.hpp"
#include "Socket.hpp"
#include "InitAddr.hpp"
using namespace std;
class Connection;
class Reactor;
using func_t = function<void(Connection*)>;


class Connection {
public :
    Connection(int sockfd, uint32_t events, Reactor* r) 
        :_sockfd(sockfd)
        ,_events(events)
        ,_R(r)
        ,_addr(nullptr)
    {

    }

    void RegisterFunc(func_t recver, func_t sender, func_t excepter) {
        _recver = recver;
        _sender = sender;
        _excepter = excepter;
    }
    int SockFd() {
        return _sockfd;
    }
    void SetAddr(struct sockaddr_in addr) {
        _addr = new InitAddr(addr);

    }
    uint32_t Events() {
        return _events;
    }

    string Get_Info() {
        return _addr->get_Info();
    }

    void AddInbuffer(string message) {
        _inbuffer += message;
    }
    void AddOutbuffer(string message) {
        _outbuffer += message;
    }
    string& Inbuffer() {
        return _inbuffer;
    }
    string& Outbuffer() {
        return _outbuffer;
    }
    bool OutbufferEmpty() {
        return _outbuffer.empty();
    }

    void SetEvents(uint32_t events) {
        _events = events;
    }
    ~Connection() {

    }
private :
    int _sockfd;
    uint32_t _events;
    string _inbuffer;
    string _outbuffer;
    InitAddr* _addr;
public :
    func_t _recver;
    func_t _sender;
    func_t _excepter;
    Reactor* _R;
};


class ConnFactory {
public :
    static Connection* BuildListenConnection(int sockfd, func_t recver, uint32_t events, Reactor* r) {
        Connection* listen_conn = new Connection(sockfd, events, r);
        listen_conn->RegisterFunc(recver, nullptr, nullptr);
        return listen_conn;
    }    

    static Connection* BuildNormalConnection(int sockfd, func_t recver, func_t sender, func_t excepter, uint32_t events, Reactor* r) {
        Connection* normal_conn = new Connection(sockfd, events, r);
        normal_conn->RegisterFunc(recver, sender, excepter);
        return normal_conn;
    }
};